package com.xyht.sca_s.student_manage_system.modules.tips.utils;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgUserRelation;
import com.xyht.sca_s.student_manage_system.modules.tips.entity.SmsTips;
import com.xyht.sca_s.student_manage_system.modules.tips.entity.SmsTipsRecord;
import com.xyht.sca_s.student_manage_system.modules.tips.entity.resp.SmsUserAndOrgRelationResp;
import com.xyht.sca_s.student_manage_system.modules.tips.entity.resp.SmsUserAndRoleRelationResp;
import com.xyht.sca_s.student_manage_system.modules.tips.mapper.SmsTipsMapper;
import com.xyht.sca_s.student_manage_system.modules.tips.mapper.SmsTipsRecordMapper;
import com.xyht.sca_s.student_manage_system.modules.tips.mapper.SmsUserAndOrgMpjMapper;
import com.xyht.sca_s.student_manage_system.modules.tips.mapper.SmsUserAndRoleMpjMapper;
import com.xyht.sca_s.student_manage_system.modules.tips.service.SmsTipsRecordService;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUserRoleRelation;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import com.xyht.sca_s.student_manage_system.modules.websocket.entity.WebsocketResult;
import com.xyht.sca_s.student_manage_system.modules.websocket.service.WebSocketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.modules.tips.constant.RangeTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.TipsCloseFlagConstant.TIPS_CLOSE;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.TipsCloseFlagConstant.TIPS_OPEN;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.TipsDoneFlagConstant.TIPS_DONE;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.TipsDoneFlagConstant.TIPS_NOT_DONE;
import static com.xyht.sca_s.student_manage_system.modules.tips.constant.UserTypeConstant.USER_TYPE_ALL;
import static com.xyht.sca_s.student_manage_system.modules.websocket.myEnum.WebsocketResultEnum.TIPS_INFORM;

@Component
public class TipsUtil {
    @Autowired
    private SmsTipsMapper smsTipsMapper;
    @Autowired
    private SmsTipsRecordMapper smsTipsRecordMapper;
    @Autowired
    private SmsTipsRecordService smsTipsRecordService;
    @Autowired
    private SmsUserMapper smsUserMapper;
    @Autowired
    private SmsUserAndOrgMpjMapper smsUserAndOrgMpjMapper;
    @Autowired
    private SmsUserAndRoleMpjMapper smsUserAndRoleMpjMapper;
    @Autowired
    private WebSocketService webSocketService;


    @Transactional
    public void addTips(String title, String description, Integer type, String app_name,
                        Integer range_type, String range, String event_id, Integer user_type, Date expirationTime) {
        try {
            //添加到消息待办表
            SmsTips smsTips = new SmsTips();
            smsTips.setTitle(title);
            smsTips.setDescription(description);
            smsTips.setType(type);
            smsTips.setAppName(app_name);
            smsTips.setRangeType(range_type);
            smsTips.setTipsRange(range);
            smsTips.setEventId(event_id);
            smsTips.setUserType(user_type);
            smsTips.setExpirationTime(expirationTime);
            smsTipsMapper.insert(smsTips);

            //添加到对应个人消息待办关系表
            List<String> userIDList = new ArrayList<>();
            if (smsTips.getRangeType() == RANGE_TYPE_ALL) {
                //添加所有人到关系表
                QueryWrapper<SmsUser> userQueryWrapper = new QueryWrapper<>();
                if (user_type != USER_TYPE_ALL) {
                    userQueryWrapper.lambda().eq(SmsUser::getFlag, user_type);
                }
                List<SmsUser> smsUserList = smsUserMapper.selectList(userQueryWrapper);
                userIDList = smsUserList.stream().map(SmsUser::getId).collect(Collectors.toList());
            } else {
                List<String> rangeList = JSONObject.parseArray(smsTips.getTipsRange(), String.class);
                if (rangeList != null && rangeList.size() > 0) {
                    switch (smsTips.getRangeType()) {
                        //添加指定人到关系表
                        case RANGE_TYPE_PERSON:
                            userIDList = rangeList;
                            break;
                        //添加指定组织中的人到关系表
                        case RANGE_TYPE_ORG:
                            MPJLambdaWrapper<SmsOrgUserRelation> mpjLambdaWrapper = new MPJLambdaWrapper<>();
                            mpjLambdaWrapper.selectAll(SmsOrgUserRelation.class)
                                    .selectAll(SmsUser.class)
                                    .leftJoin(SmsUser.class, SmsUser::getId, SmsOrgUserRelation::getUserId)
                                    .in(SmsOrgUserRelation::getOrgId, rangeList);
                            if (user_type != USER_TYPE_ALL) {
                                mpjLambdaWrapper.eq(SmsUser::getFlag, user_type);
                            }
                            List<SmsUserAndOrgRelationResp> smsUserOrgList = smsUserAndOrgMpjMapper.selectJoinList(SmsUserAndOrgRelationResp.class, mpjLambdaWrapper);
                            userIDList = smsUserOrgList.stream().map(SmsUserAndOrgRelationResp::getUserId).collect(Collectors.toList());
                            break;
                        //添加指定角色中的人到关系表
                        case RANGE_TYPE_ROLE:
                            MPJLambdaWrapper<SmsUserRoleRelation> mpjWrapper = new MPJLambdaWrapper<>();
                            mpjWrapper.selectAll(SmsUserRoleRelation.class)
                                    .selectAll(SmsUser.class)
//                                    .selectAs(SmsUserRoleRelation::getUserId,"id")
                                    .selectAs(SmsOrgUserRelation::getId, "relation_id")
                                    .leftJoin(SmsUser.class, SmsUser::getId, SmsUserRoleRelation::getUserId)
                                    .in(SmsUserRoleRelation::getRoleId, rangeList);
                            if (user_type != USER_TYPE_ALL) {
                                mpjWrapper.eq(SmsUser::getFlag, user_type);
                            }
                            List<SmsUserAndRoleRelationResp> smsUserRoleList = smsUserAndRoleMpjMapper.selectJoinList(SmsUserAndRoleRelationResp.class, mpjWrapper);
                            userIDList = smsUserRoleList.stream().map(SmsUserAndRoleRelationResp::getUserId).collect(Collectors.toList());
                            break;
                    }
                }
            }
            if (userIDList.size() > 0) {
                List<SmsTipsRecord> saveRecord = new ArrayList<>();
                for (String user_id : userIDList) {
                    SmsTipsRecord smsTipsRecord = new SmsTipsRecord();
                    smsTipsRecord.setUserId(user_id);
                    smsTipsRecord.setTipsId(smsTips.getId());
                    smsTipsRecord.setIsDone(TIPS_NOT_DONE);
                    saveRecord.add(smsTipsRecord);
                }
                smsTipsRecordService.saveBatch(saveRecord);
                //发送界面更新消息
                webSocketService.batchSend(userIDList, null, WebsocketResult.success(TIPS_INFORM));
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    //结束个人/所有人消息待办记录-已读  结束整个消息通知is_close
    @Transactional
    public void finishTips(String event_id, String user_id, Integer is_close) {
        try {
            SmsTips smsTips = smsTipsMapper.selectOne(new QueryWrapper<SmsTips>()
                    .lambda()
                    .eq(SmsTips::getEventId, event_id)
                    .eq(SmsTips::getIsClose, TIPS_OPEN));

            if (smsTips == null || smsTips.getId() == null) {
                return;
            }

            SmsTipsRecord smsTipsRecord = new SmsTipsRecord();
            smsTipsRecord.setIsDone(TIPS_DONE);
            QueryWrapper<SmsTipsRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(SmsTipsRecord::getTipsId, smsTips.getId());
            if (user_id != null && !user_id.equals("")) {
                queryWrapper.lambda()
                        .eq(SmsTipsRecord::getUserId, user_id);
            }
            smsTipsRecordMapper.update(smsTipsRecord, queryWrapper);

            if (is_close != null && is_close == TIPS_CLOSE) {
                closeTips(event_id);
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    @Transactional
    public void closeTips(String event_id) {
        try {
            SmsTips smsTips = new SmsTips();
            smsTips.setIsClose(TIPS_CLOSE);
            smsTips.setExpirationTime(new Date());
            smsTipsMapper.update(smsTips, new QueryWrapper<SmsTips>()
                    .lambda()
                    .eq(SmsTips::getEventId, event_id));
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }


}
